{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "## CNN+LSTM    12通道   12seq_len    9轮  22轮   线上18分\n",
    "##   https://tianchi.aliyun.com/forum/postDetail?postId=176735"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import torch\n",
    "from copy import deepcopy\n",
    "import numpy as np\n",
    "import xarray as xr\n",
    "import pandas as pd\n",
    "import torch.nn as nn\n",
    "import random\n",
    "from tqdm import tqdm\n",
    "from sklearn.model_selection import train_test_split\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "import zipfile\n",
    "import torchvision.models as models\n",
    "\n",
    "# python ref/train.py \n",
    "def set_seed(seed = 123):\n",
    "    random.seed(seed)\n",
    "    np.random.seed(seed)\n",
    "    os.environ['PYTHONHASHSEED'] = str(seed)\n",
    "    torch.manual_seed(seed)\n",
    "\n",
    "\n",
    "def load_data2():\n",
    "    # CMIP data    \n",
    "    #PATH = './tcdata/enso_round1_train_20210201/'\n",
    "    #PATH = 'E:/enso_round1_train_20210201/'\n",
    "    PATH = './data/'\n",
    "    train = xr.open_dataset(PATH+'CMIP_train.nc')\n",
    "    label = xr.open_dataset(PATH+'CMIP_label.nc')  \n",
    "   \n",
    "    train_sst = train['sst'][:, :12].values  # (4645, 12, 24, 72)\n",
    "    train_t300 = train['t300'][:, :12].values\n",
    "    train_ua = train['ua'][:, :12].values\n",
    "    train_va = train['va'][:, :12].values\n",
    "    train_label = label['nino'][:, 12:36].values\n",
    "    \n",
    "    m = np.zeros(train_ua.shape[0])\n",
    "    for i in range(train_ua.shape[0]):\n",
    "        if np.sum(np.isnan(train_ua[i])) != 0:\n",
    "            m[i] = np.sum(np.isnan(train_ua[i]))\n",
    "\n",
    "    #将有缺失值的数据 剔除，选择缺失值为0的数据\n",
    "    train_sst = train_sst[np.where(m==0)[0]]\n",
    "    train_t300 = train_t300[np.where(m==0)[0]]\n",
    "    train_ua = train_ua[np.where(m==0)[0]]\n",
    "    train_va = train_va[np.where(m==0)[0]]\n",
    "    train_label = train_label[np.where(m==0)[0]]\n",
    "\n",
    "    N = int(len(train_label)*0.8)\n",
    "    print('Train samples: {}, Valid samples: {}'.format(len(train_label[:N]), len(train_label[N:])))\n",
    "\n",
    "    dict_train = {\n",
    "        'sst':train_sst[:N],\n",
    "        't300':train_t300[:N],\n",
    "        'ua':train_ua[:N],\n",
    "        'va': train_va[:N],\n",
    "        'label': train_label[:N]}\n",
    "    dict_valid = {\n",
    "        'sst':train_sst[N:],\n",
    "        't300':train_t300[N:],\n",
    "        'ua':train_ua[N:],\n",
    "        'va': train_va[N:],\n",
    "        'label': train_label[N:]}\n",
    "    \n",
    "    train_dataset = EarthDataSet(dict_train)\n",
    "    valid_dataset = EarthDataSet(dict_valid)\n",
    "    return train_dataset, valid_dataset\n",
    "    \n",
    "\n",
    "class EarthDataSet(Dataset):\n",
    "    def __init__(self, data):\n",
    "        self.data = data\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.data['sst'])\n",
    "\n",
    "    def __getitem__(self, idx):   \n",
    "        return (self.data['sst'][idx], self.data['t300'][idx], self.data['ua'][idx], self.data['va'][idx]), self.data['label'][idx]\n",
    "\n",
    "\n",
    "class simpleSpatailTimeNN(nn.Module):\n",
    "    def __init__(self, n_cnn_layer:int=1, kernals:list=[3], n_lstm_units:int=64):\n",
    "        super(simpleSpatailTimeNN, self).__init__()\n",
    "        self.conv1 = nn.ModuleList([nn.Conv2d(in_channels=12, out_channels=12, kernel_size=i) for i in kernals]) \n",
    "        self.conv2 = nn.ModuleList([nn.Conv2d(in_channels=12, out_channels=12, kernel_size=i) for i in kernals])\n",
    "        self.conv3 = nn.ModuleList([nn.Conv2d(in_channels=12, out_channels=12, kernel_size=i) for i in kernals])\n",
    "        self.conv4 = nn.ModuleList([nn.Conv2d(in_channels=12, out_channels=12, kernel_size=i) for i in kernals])\n",
    "        self.pool1 = nn.AdaptiveAvgPool2d((22, 1))\n",
    "        self.pool2 = nn.AdaptiveAvgPool2d((1, 70))\n",
    "        self.pool3 = nn.AdaptiveAvgPool2d((1, 128))\n",
    "        self.batch_norm = nn.BatchNorm1d(12, affine=False)\n",
    "        self.lstm = nn.LSTM(22*70 * 4, n_lstm_units, 2, bidirectional=True, batch_first=True)\n",
    "        self.linear = nn.Linear(128, 24)\n",
    "\n",
    "    def forward(self, sst, t300, ua, va):\n",
    "        for conv1 in self.conv1:\n",
    "            sst = conv1(sst)  # batch * 12 * (24 - 2) * (72 -2)\n",
    "        for conv2 in self.conv2:\n",
    "            t300 = conv2(t300)\n",
    "        for conv3 in self.conv3:\n",
    "            ua = conv3(ua)\n",
    "        for conv4 in self.conv4:\n",
    "            va = conv4(va)\n",
    "\n",
    "        sst = torch.flatten(sst, start_dim=2)  # batch * 12 * 1540\n",
    "        t300 = torch.flatten(t300, start_dim=2)\n",
    "        ua = torch.flatten(ua, start_dim=2)\n",
    "        va = torch.flatten(va, start_dim=2)  # if flat, lstm input_dims = 1540 * 4              \n",
    "            \n",
    "        x = torch.cat([sst, t300, ua, va], dim=-1)    \n",
    "        x = self.batch_norm(x)\n",
    "        x, _ = self.lstm(x)\n",
    "        x = self.pool3(x).squeeze(dim=-2)\n",
    "        x = self.linear(x)\n",
    "        return x\n",
    "\n",
    "\n",
    "def coreff(x, y):\n",
    "    x_mean = np.mean(x)\n",
    "    y_mean = np.mean(y)\n",
    "    c1 = sum((x - x_mean) * (y - y_mean))\n",
    "    c2 = sum((x - x_mean)**2) * sum((y - y_mean)**2)\n",
    "    return c1/np.sqrt(c2)\n",
    "\n",
    "def rmse(preds, y):\n",
    "    return np.sqrt(sum((preds - y)**2)/preds.shape[0])\n",
    "\n",
    "def eval_score(preds, label):\n",
    "    # preds = preds.cpu().detach().numpy().squeeze()\n",
    "    # label = label.cpu().detach().numpy().squeeze()\n",
    "    acskill = 0\n",
    "    RMSE = 0\n",
    "    a = 0\n",
    "    a = [1.5]*4 + [2]*7 + [3]*7 + [4]*6\n",
    "    for i in range(24):\n",
    "        RMSE += rmse(label[:, i], preds[:, i])\n",
    "        cor = coreff(label[:, i], preds[:, i])\n",
    "    \n",
    "        acskill += a[i] * np.log(i+1) * cor\n",
    "    return 2/3 * acskill - RMSE\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "def train():\n",
    "    fit_params = {\n",
    "    'n_epochs' : 10,\n",
    "    'learning_rate' : 0.0001,\n",
    "    'batch_size' : 100,}\n",
    "\n",
    "    set_seed()\n",
    "    best_sco = -1000\n",
    "    train_dataset, valid_dataset = load_data2()      \n",
    "    train_loader = DataLoader(train_dataset, batch_size=fit_params['batch_size'])\n",
    "    valid_loader = DataLoader(valid_dataset, batch_size=fit_params['batch_size'])\n",
    "    best_sco = -1000\n",
    "    model = simpleSpatailTimeNN()\n",
    "    device = 'cpu'\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr=fit_params['learning_rate'])\n",
    "    loss_fn = nn.MSELoss()   \n",
    "    \n",
    "    model.to(device)\n",
    "    loss_fn.to(device)\n",
    "\n",
    "    for i in range(fit_params['n_epochs']):\n",
    "        model.train()\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(train_loader): \n",
    "            #print(sst.shape)\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            optimizer.zero_grad()\n",
    "            label = label.to(device).float()\n",
    "            #print(sst.shape)\n",
    "            preds = model(sst,t300,ua,va)\n",
    "            loss = loss_fn(preds, label)\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            #print('Step: {}, Train Loss: {}'.format(step, loss))\n",
    "            \n",
    "        model.eval()\n",
    "        y_true, y_pred = [], []\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(train_loader):\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            label = label.to(device).float()\n",
    "            preds = model(sst,t300,ua,va)\n",
    "\n",
    "            y_pred.append(preds)\n",
    "            y_true.append(label)\n",
    "\n",
    "        y_true = torch.cat(y_true, axis=0)\n",
    "        y_pred = torch.cat(y_pred, axis=0)\n",
    "        score = eval_score(y_true.cpu().detach().numpy(), y_pred.cpu().detach().numpy())\n",
    "        ls = loss_fn(y_pred,y_true).cpu().detach().numpy()\n",
    "        print(\"Epoch: {} Train acc: {}  Train loss: {}\".format(i+1,round(score,2),ls))\n",
    "        \n",
    "#         model.eval()\n",
    "        y_true, y_pred = [], []\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(valid_loader):\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            label = label.to(device).float()\n",
    "            preds = model(sst,t300,ua,va)\n",
    "\n",
    "            y_pred.append(preds)\n",
    "            y_true.append(label)\n",
    "\n",
    "        y_true = torch.cat(y_true, axis=0)\n",
    "        y_pred = torch.cat(y_pred, axis=0)\n",
    "        score = eval_score(y_true.cpu().detach().numpy(), y_pred.cpu().detach().numpy())\n",
    "        ls = loss_fn(y_pred,y_true).cpu().detach().numpy()\n",
    "        print(\"Epoch: {} Test acc: {}   Test loss: {}\".format(i+1,round(score,2),ls))\n",
    "        \n",
    "        if score>best_sco:\n",
    "            best_sco = score\n",
    "            PATH = './user_data/retrainref.pt'\n",
    "            torch.save(model.state_dict(), PATH)\n",
    "            #torch.save(model, './user_data/ref.pkl')\n",
    "            print('Model saved successfully')\n",
    "\n",
    "\n",
    "\n",
    "def load_data2_SODA(ratio = 0.8):  \n",
    "    # CMIP data    \n",
    "    #PATH = './tcdata/enso_round1_train_20210201/'\n",
    "    #PATH = 'E:/enso_round1_train_20210201/'\n",
    "    PATH = './data/'\n",
    "    train2 = xr.open_dataset(PATH+'SODA_train.nc')\n",
    "    label2 = xr.open_dataset(PATH+'SODA_label.nc')  \n",
    "    train_sst2 = train2['sst'][:, :12].values  # (4645, 12, 24, 72)\n",
    "    train_t3002 = train2['t300'][:, :12].values\n",
    "    train_ua2 = train2['ua'][:, :12].values\n",
    "    train_va2 = train2['va'][:, :12].values\n",
    "    train_label2 = label2['nino'][:, 12:36].values\n",
    "    \n",
    "    m = np.zeros(train_ua2.shape[0])\n",
    "    for i in range(train_ua2.shape[0]):\n",
    "        if np.sum(np.isnan(train_ua2[i])) != 0:\n",
    "            m[i] = np.sum(np.isnan(train_ua2[i]))\n",
    "\n",
    "    #将有缺失值的数据 剔除，选择缺失值为0的数据\n",
    "    train_sst2 = train_sst2[np.where(m==0)[0]]\n",
    "    train_t3002 = train_t3002[np.where(m==0)[0]]\n",
    "    train_ua2 = train_ua2[np.where(m==0)[0]]\n",
    "    train_va2 = train_va2[np.where(m==0)[0]]\n",
    "    train_label2 = train_label2[np.where(m==0)[0]]\n",
    "    \n",
    "    \n",
    "    #测试集比例变动对其结果影响很大！\n",
    "    N = int(len(train_sst2)* ratio)\n",
    "    print('Train samples: {}, Valid samples: {}'.format(len(train_label2[:N]), len(train_label2[N:])))\n",
    "    \n",
    "    dict_train = {\n",
    "        'sst':     train_sst2[2:N],\n",
    "        't300':   train_t3002[2:N],\n",
    "        'ua':       train_ua2[2:N],\n",
    "        'va':       train_va2[2:N],\n",
    "        'label': train_label2[2:N]}\n",
    "    dict_valid = {\n",
    "        'sst':     train_sst2[N:],\n",
    "        't300':   train_t3002[N:],\n",
    "        'ua':       train_ua2[N:],\n",
    "        'va':       train_va2[N:],\n",
    "        'label': train_label2[N:]}\n",
    "    \n",
    "    train_dataset = EarthDataSet(dict_train)\n",
    "    valid_dataset = EarthDataSet(dict_valid)\n",
    "    return train_dataset, valid_dataset\n",
    "\n",
    "\n",
    "\n",
    "def retrain():\n",
    "    set_seed()\n",
    "    best_sco = -1000\n",
    "    fit_params = {\n",
    "        'n_epochs' : 22,\n",
    "        'learning_rate' : 0.00005,\n",
    "        'batch_size' : 100,\n",
    "    }\n",
    "    \n",
    "    train_dataset, valid_dataset = load_data2_SODA()      \n",
    "    train_loader = DataLoader(train_dataset, batch_size=fit_params['batch_size'])\n",
    "    valid_loader = DataLoader(valid_dataset, batch_size=fit_params['batch_size'])\n",
    "    \n",
    "    # Specify a path\n",
    "    PATH = './user_data/retrainref.pt'\n",
    "    # Load\n",
    "    model = simpleSpatailTimeNN()\n",
    "    model.load_state_dict(torch.load(PATH))\n",
    "    device = 'cpu'\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr=fit_params['learning_rate'])\n",
    "    loss_fn = nn.MSELoss()   \n",
    "    \n",
    "    model.to(device)\n",
    "    loss_fn.to(device)\n",
    "\n",
    "    for i in range(fit_params['n_epochs']):\n",
    "        model.train()\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(train_loader): \n",
    "            #print(sst.shape)\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            optimizer.zero_grad()\n",
    "            label = label.to(device).float()\n",
    "            #print(sst.shape)\n",
    "            preds = model(sst,t300,ua,va)\n",
    "            loss = loss_fn(preds, label)\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            #print('Step: {}, Train Loss: {}'.format(step, loss))\n",
    "            \n",
    "        model.eval()\n",
    "        y_true, y_pred = [], []\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(train_loader):\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            label = label.to(device).float()\n",
    "            preds = model(sst,t300,ua,va)\n",
    "\n",
    "            y_pred.append(preds)\n",
    "            y_true.append(label)\n",
    "\n",
    "        y_true = torch.cat(y_true, axis=0)\n",
    "        y_pred = torch.cat(y_pred, axis=0)\n",
    "        score = eval_score(y_true.cpu().detach().numpy(), y_pred.cpu().detach().numpy())\n",
    "        ls = loss_fn(y_pred,y_true).cpu().detach().numpy()\n",
    "        print(\"Epoch: {} Train acc: {}  Train loss: {}\".format(i+1,round(score,2),ls))\n",
    "        \n",
    "#         model.eval()\n",
    "        y_true, y_pred = [], []\n",
    "        for step, ((sst, t300, ua, va), label) in enumerate(valid_loader):\n",
    "            sst = sst.to(device).float()\n",
    "            t300 = t300.to(device).float()\n",
    "            ua = ua.to(device).float()\n",
    "            va = va.to(device).float()\n",
    "            label = label.to(device).float()\n",
    "            preds = model(sst,t300,ua,va)\n",
    "\n",
    "            y_pred.append(preds)\n",
    "            y_true.append(label)\n",
    "\n",
    "        y_true = torch.cat(y_true, axis=0)\n",
    "        y_pred = torch.cat(y_pred, axis=0)\n",
    "        score = eval_score(y_true.cpu().detach().numpy(), y_pred.cpu().detach().numpy())\n",
    "        ls = loss_fn(y_pred,y_true).cpu().detach().numpy()\n",
    "        print(\"Epoch: {} Test acc: {}   Test loss: {}\".format(i+1,round(score,2),ls))\n",
    "        \n",
    "        if score>best_sco:\n",
    "            best_sco = score\n",
    "            PATH = './user_data/ref.pt'\n",
    "            torch.save(model.state_dict(), PATH)\n",
    "            #torch.save(model, './user_data/ref.pkl')\n",
    "            print('Model saved successfully')\n",
    "\n",
    "\n",
    "def submit():\n",
    "    # Specify a path\n",
    "    PATH = './user_data/ref.pt'\n",
    "    # Load\n",
    "    model = simpleSpatailTimeNN()\n",
    "    model.load_state_dict(torch.load(PATH,map_location='cpu'))\n",
    "    model.eval()\n",
    "\n",
    "    #test_path = './tcdata/enso_final_test_data_B/'\n",
    "    test_path = './tcdata/enso_round1_test_20210201/'\n",
    "    #device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "    device = 'cpu'\n",
    "    ### 1. 测试数据读取\n",
    "    files = os.listdir(test_path)\n",
    "    test_feas_dict = {}\n",
    "    for file in files:\n",
    "        test_feas_dict[file] = np.load(test_path + file)\n",
    "\n",
    "    ### 2. 结果预测\n",
    "    test_predicts_dict = {}\n",
    "    for file_name, val in test_feas_dict.items():\n",
    "        sst = val[:, :, :, 0]\n",
    "        t300 = val[:, :, :, 1]\n",
    "        ua = val[:, :, :, 2]\n",
    "        va = val[:, :, :, 3]\n",
    "        sst = torch.tensor(sst).float().reshape(-1, 12, 24, 72)\n",
    "        t300 = torch.tensor(t300).float().reshape(-1, 12, 24, 72)\n",
    "        ua = torch.tensor(ua).float().reshape(-1, 12, 24, 72)\n",
    "        va = torch.tensor(va).float().reshape(-1, 12, 24, 72)\n",
    "        test_predicts_dict[file_name] = model(sst, t300, ua, va).reshape(-1, )\n",
    "        print(len(test_predicts_dict))\n",
    "    ### 3.存储预测结果\n",
    "    if not os.path.exists('./result'):\n",
    "        os.makedirs('./result')\n",
    "    for file_name, val in test_predicts_dict.items():\n",
    "        np.save('./result/' + file_name, val.detach().numpy())\n",
    "\n",
    "        # 打包目录为zip文件（未压缩）\n",
    "\n",
    "\n",
    "    def make_zip(source_dir='./result/', output_filename='result.zip'):\n",
    "        zipf = zipfile.ZipFile(output_filename, 'w')\n",
    "        pre_len = len(os.path.dirname(source_dir))\n",
    "        source_dirs = os.walk(source_dir)\n",
    "        print(source_dirs)\n",
    "        for parent, dirnames, filenames in source_dirs:\n",
    "            print(parent, dirnames)\n",
    "            for filename in filenames:\n",
    "                if '.npy' not in filename:\n",
    "                    continue\n",
    "                pathfile = os.path.join(parent, filename)\n",
    "                arcname = pathfile[pre_len:].strip(os.path.sep)  # 相对路径\n",
    "                zipf.write(pathfile, arcname)\n",
    "        zipf.close()\n",
    "\n",
    "\n",
    "    make_zip()\n",
    "    print('==========================end==========================')\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train samples: 3112, Valid samples: 778\n",
      "Epoch: 1 Train acc: -7.99  Train loss: 0.6829770803451538\n",
      "Epoch: 1 Test acc: -17.61   Test loss: 0.5815464854240417\n",
      "Model saved successfully\n",
      "Epoch: 2 Train acc: 6.61  Train loss: 0.6681841015815735\n",
      "Epoch: 2 Test acc: -12.36   Test loss: 0.5785638093948364\n",
      "Model saved successfully\n",
      "Epoch: 3 Train acc: 21.97  Train loss: 0.6356195211410522\n",
      "Epoch: 3 Test acc: 1.25   Test loss: 0.568675696849823\n",
      "Model saved successfully\n",
      "Epoch: 4 Train acc: 28.13  Train loss: 0.5825234055519104\n",
      "Epoch: 4 Test acc: 13.49   Test loss: 0.5458896160125732\n",
      "Model saved successfully\n",
      "Epoch: 5 Train acc: 35.27  Train loss: 0.5311795473098755\n",
      "Epoch: 5 Test acc: 21.82   Test loss: 0.5154002904891968\n",
      "Model saved successfully\n",
      "Epoch: 6 Train acc: 40.76  Train loss: 0.48163291811943054\n",
      "Epoch: 6 Test acc: 26.28   Test loss: 0.48750823736190796\n",
      "Model saved successfully\n",
      "Epoch: 7 Train acc: 47.05  Train loss: 0.4348689317703247\n",
      "Epoch: 7 Test acc: 28.63   Test loss: 0.46865612268447876\n",
      "Model saved successfully\n",
      "Epoch: 8 Train acc: 53.55  Train loss: 0.38884350657463074\n",
      "Epoch: 8 Test acc: 29.88   Test loss: 0.456137478351593\n",
      "Model saved successfully\n",
      "Epoch: 9 Train acc: 60.3  Train loss: 0.34247568249702454\n",
      "Epoch: 9 Test acc: 30.39   Test loss: 0.44795918464660645\n",
      "Model saved successfully\n",
      "Epoch: 10 Train acc: 67.33  Train loss: 0.29527100920677185\n",
      "Epoch: 10 Test acc: 30.32   Test loss: 0.4432799220085144\n",
      "Train samples: 80, Valid samples: 20\n",
      "Epoch: 1 Train acc: 6.32  Train loss: 0.6605164408683777\n",
      "Epoch: 1 Test acc: 16.98   Test loss: 0.4147578179836273\n",
      "Model saved successfully\n",
      "Epoch: 2 Train acc: 9.52  Train loss: 0.6319741606712341\n",
      "Epoch: 2 Test acc: 17.08   Test loss: 0.4140484631061554\n",
      "Model saved successfully\n",
      "Epoch: 3 Train acc: 12.84  Train loss: 0.6057603359222412\n",
      "Epoch: 3 Test acc: 17.18   Test loss: 0.4133550822734833\n",
      "Model saved successfully\n",
      "Epoch: 4 Train acc: 16.16  Train loss: 0.5823343396186829\n",
      "Epoch: 4 Test acc: 17.28   Test loss: 0.41267916560173035\n",
      "Model saved successfully\n",
      "Epoch: 5 Train acc: 19.4  Train loss: 0.5617654323577881\n",
      "Epoch: 5 Test acc: 17.38   Test loss: 0.4120219051837921\n",
      "Model saved successfully\n",
      "Epoch: 6 Train acc: 22.52  Train loss: 0.5437968969345093\n",
      "Epoch: 6 Test acc: 17.49   Test loss: 0.4113825261592865\n",
      "Model saved successfully\n",
      "Epoch: 7 Train acc: 25.51  Train loss: 0.5280328989028931\n",
      "Epoch: 7 Test acc: 17.6   Test loss: 0.41076210141181946\n",
      "Model saved successfully\n",
      "Epoch: 8 Train acc: 28.37  Train loss: 0.5140853524208069\n",
      "Epoch: 8 Test acc: 17.72   Test loss: 0.410162091255188\n",
      "Model saved successfully\n",
      "Epoch: 9 Train acc: 31.11  Train loss: 0.5016206502914429\n",
      "Epoch: 9 Test acc: 17.83   Test loss: 0.4095836579799652\n",
      "Model saved successfully\n",
      "Epoch: 10 Train acc: 33.73  Train loss: 0.49036040902137756\n",
      "Epoch: 10 Test acc: 17.95   Test loss: 0.40902745723724365\n",
      "Model saved successfully\n",
      "Epoch: 11 Train acc: 36.22  Train loss: 0.48007696866989136\n",
      "Epoch: 11 Test acc: 18.07   Test loss: 0.40849387645721436\n",
      "Model saved successfully\n",
      "Epoch: 12 Train acc: 38.59  Train loss: 0.47058698534965515\n",
      "Epoch: 12 Test acc: 18.18   Test loss: 0.4079831838607788\n",
      "Model saved successfully\n",
      "Epoch: 13 Train acc: 40.83  Train loss: 0.461747407913208\n",
      "Epoch: 13 Test acc: 18.29   Test loss: 0.4074952304363251\n",
      "Model saved successfully\n",
      "Epoch: 14 Train acc: 42.94  Train loss: 0.4534502625465393\n",
      "Epoch: 14 Test acc: 18.4   Test loss: 0.4070298373699188\n",
      "Model saved successfully\n",
      "Epoch: 15 Train acc: 44.92  Train loss: 0.44561511278152466\n",
      "Epoch: 15 Test acc: 18.51   Test loss: 0.4065859019756317\n",
      "Model saved successfully\n",
      "Epoch: 16 Train acc: 46.77  Train loss: 0.43818041682243347\n",
      "Epoch: 16 Test acc: 18.61   Test loss: 0.4061625301837921\n",
      "Model saved successfully\n",
      "Epoch: 17 Train acc: 48.5  Train loss: 0.43109622597694397\n",
      "Epoch: 17 Test acc: 18.71   Test loss: 0.40575847029685974\n",
      "Model saved successfully\n",
      "Epoch: 18 Train acc: 50.1  Train loss: 0.42432117462158203\n",
      "Epoch: 18 Test acc: 18.81   Test loss: 0.4053729474544525\n",
      "Model saved successfully\n",
      "Epoch: 19 Train acc: 51.59  Train loss: 0.4178219139575958\n",
      "Epoch: 19 Test acc: 18.9   Test loss: 0.40500494837760925\n",
      "Model saved successfully\n",
      "Epoch: 20 Train acc: 52.98  Train loss: 0.4115726351737976\n",
      "Epoch: 20 Test acc: 18.99   Test loss: 0.40465405583381653\n",
      "Model saved successfully\n",
      "Epoch: 21 Train acc: 54.27  Train loss: 0.4055537283420563\n",
      "Epoch: 21 Test acc: 19.08   Test loss: 0.40431997179985046\n",
      "Model saved successfully\n",
      "Epoch: 22 Train acc: 55.47  Train loss: 0.399749755859375\n",
      "Epoch: 22 Test acc: 19.17   Test loss: 0.40400248765945435\n",
      "Model saved successfully\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "<generator object walk at 0x000001D1A2855448>\n",
      "./result/ []\n",
      "==========================end==========================\n"
     ]
    }
   ],
   "source": [
    "train()\n",
    "retrain()\n",
    "submit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
